﻿/* ****************************************************************************
 *
 * Copyright (c) Microsoft Corporation. 
 *
 * This source code is subject to terms and conditions of the Microsoft Public License. A
 * copy of the license can be found at http://go.microsoft.com/fwlink/?LinkID=131993. If
 * you cannot locate the Microsoft Public License, please send an email to
 * mixon@microsoft.com. By using this source code in any fashion, you are agreeing to
 * be bound by the terms of the Microsoft Public License.
 *
 * You must not remove this notice, or any other, from this software.
 *
 *
 * ***************************************************************************/


using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Browser;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using System.Windows.Resources;

namespace MIXOnline.Descry
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();

            // get version info for properties dialog
            Assembly asm = Assembly.GetExecutingAssembly();
            string[] parts = asm.FullName.Split(',');
            this.textBlockVersion.Text = parts[1];

            // check to see how much space Isolated Storage has, if its under DESIRED_QUOTA_SIZE increase by DESIRED_QUOTA_SIZE
            // The right thing to do is throw a popup to ask the user to increase in storage if it is needed
            // This is necessary, so that we can trigger the Silverlight request, since it requires the user to 
            // initiate the request.

            // did the user decline increasing storage last time?
            Nullable<bool> declined = Storage.GetAppSettingItem("DeclinedStorageIncrease") as Nullable<bool>;

            bool? result = Storage.GetAppSettingItem("FirstRunUX") as bool?;

            if (result == null)
            {
                // show first run UX

                autoCompleteBoxUserName.Text = "Enter a Friendfeed ID";
                autoCompleteBoxUserName.GotFocus+=new RoutedEventHandler(autoCompleteBoxUserName_GotFocus);

                //gridFirstRun.Visibility = Visibility.Visible;
                //gridFirstRunOrig.Visibility = Visibility.Visible;

                Storage.SetAppSettingItem("FirstRunUX", true);
            }
            
            try
            {
                long currentQuotaSize = Storage.GetCurrentQuota();
                if (currentQuotaSize < DESIRED_QUOTA_SIZE)
                {
                    if (declined == null || declined.Value == false)
                    {
                        isolatedStorageSizeModificationDialog.SizeInBytes = DESIRED_QUOTA_SIZE;
                        isolatedStorageSizeModificationDialog.Show();
                    }
                }
            }
            catch (Exception ex)
            {
                HtmlPage.Window.SetProperty("status", ex.Message + ":" + ex.ToString());
            }

            SubscribeToEvents();

            // get Most recently used list from AppSettings
            userMRU = Storage.GetAppSettingItem("UserMRU") as List<string>;
            autoCompleteBoxUserName.ItemsSource = userMRU;
        }

        private void autoCompleteBoxUserName_GotFocus(object sender, RoutedEventArgs e)
        {
            if (autoCompleteBoxUserName.Text == "Enter a Friendfeed ID")
                autoCompleteBoxUserName.Text = "";
        }

        #region Events

        /// <summary>
        /// Fires when the timeline is finished loading up for the first time.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timeline_Loaded(object sender, RoutedEventArgs e)
        {
            // init duration ListBox
            this.listboxDuration.DataContext = timeline.Views;
            this.listboxDuration.SelectedIndex = this.listboxDuration.Items.IndexOf(timeline.View);

            // init popularity ListBox
            List<PopularityItems> popularity = new List<PopularityItems>();
            popularity.Add(new PopularityItems() { IsChecked = false, Name = "Likes" });
            popularity.Add(new PopularityItems() { IsChecked = false, Name = "Comments" });
            this.listboxPopularity.DataContext = popularity;

            Nullable<int> downloadItemCount = (Nullable<int>)Storage.GetAppSettingItem("ItemCount");
            if (downloadItemCount != null)
                this.textBoxEntriesToGet.Text = downloadItemCount.Value.ToString();

            // init username to last used, or default to scobleizer for now
            string username = Storage.GetAppSettingItem("UserName") as string;

            if (string.IsNullOrEmpty(username))
                username = ""; // for first launch UX

            this.autoCompleteBoxUserName.Text = username;

            if (string.IsNullOrEmpty(username)) return;

            TryGetUserAvatarAndData(username);

            // show loading dialog
            loadingDialog.Visibility = Visibility.Visible;

            _dataModule.ItemRequestCount = GetItemCount();

            //_dataModule.LoadData(username, false);

            _lastUserName = username; // store last used username
        }

        /// <summary>
        /// Initiates downloading data on user select
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonRefresh_Click(object sender, RoutedEventArgs e)
        {
            ClearAllFilters();
            DownloadData();
        }

        /// <summary>
        /// Initiates downloading data on user select
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonGetData_Click(object sender, RoutedEventArgs e)
        {
            ClearAllFilters();
            DownloadData();
        }

        /// <summary>
        /// Fires when the timeline finished downloading new data.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="sea"></param>
        private void timeline_ItemsChanged(object sender, TimelineEventArgs sea)
        {
            ClearDialogState();
            loadingDialog.Visibility = Visibility.Collapsed;

            timeline.Vic.Items = _dataModule.UnfilteredItems; // set itemssource and bind

            // we need to update the UI to reflect the new data
            List<User> users = _dataModule.EnumerateUsers().Cast<User>().ToList();
            //textBlockFriends.Text = "FRIENDS (" + users.Count().ToString() + ")";
            listboxUsers.DataContext = users;
            listboxUsers.Items = users;
            listboxServices.DataContext = _dataModule.EnumerateServices().Cast<Service>().ToList();

            // this centers the last EntryItem in the Timeline window
            CenterLatestItem();

        }

        /// <summary>
        /// This event fires when the timeline provides update information
        /// </summary>
        /// <param name="sender">Not used.</param>
        /// <param name="fe">Contains the update data.</param>
        private void timeline_StatusChanged(object sender, TimelineEventArgs fe)
        {
            string status = fe.Data;

            HtmlPage.Window.SetProperty("status", fe.Data);

            if (status.Contains("Downloading") || status.Contains("Loading"))
            {
                loadingDialog.Visibility = Visibility.Visible;
            }

            if (status.Contains("Display"))
            {
                loadingDialog.Visibility = Visibility.Collapsed;

                textBlockStatus.Text = fe.Data; // report status
            }
        }

        /// <summary>
        /// This event fires if no valid URI for an image was found
        /// </summary>
        /// <param name="sender">Not used.</param>
        /// <param name="e">Not used</param>
        private void imageProfile_ImageFailed(object sender, ExceptionRoutedEventArgs e)
        {
            // reset app to determinate state
            //

            HtmlPage.Window.SetProperty("status", "FriendFeed ID is not found, or network is unavailable.");
            loadingDialog.Visibility = Visibility.Collapsed; // hide Loading dialog
            textBlockStatus.Text = "Displaying 0 of 0 Posts. User not found. Try again or click \"search for user\""; // clear status
            removeFilters.Visibility = Visibility.Collapsed;

            // clear all data and update the UI to reflect the new data
            List<User> users = _dataModule.EnumerateUsers().Cast<User>().ToList();
            listboxUsers.DataContext = users;
            listboxUsers.Items = users;
            listboxServices.DataContext = _dataModule.EnumerateServices().Cast<Service>().ToList();

            // load up default image from a resource
            imageProfile.Source = GetImageFromResource("Timeline;component/images/default_user_thumb.png");

            // let the page know that the request for image failed so that it stops trying to get data for a non-existant user.
            // FriendFeed API does not make a callback when no user is found, since the approach that we are using via the DOM does not return
            // any script when IE gets a 404. it just ignores the data returned.
            // So that this is somewhat deterministic, we need to take this approach.
            _invalidUser = true;
        }

        /// <summary>
        /// This event fires when an image is done downloading.
        /// </summary>
        /// <param name="sender">Not used</param>
        /// <param name="e">When this value is 100 check to see if the ImageFailed event had fired</param>
        private void image_DownloadProgress(object sender, DownloadProgressEventArgs e)
        {
            // for this event to work depends on the ImageFailed Event firing first. So far it seems to be doing that.
            // the issue is that we cannot determine if the image loaded successfully because there is no
            // event that fires when this happens, so we have to wait for the progress to be 100% and then
            // check to see if the download failed. If it didn't then we hope that it succeeded and we can
            // tell the dataModule to go ahead and get the data for this user.

            if (e.Progress == 100)
            {
                Dispatcher.BeginInvoke(delegate()
                {
                    if (!_invalidUser)
                    {
                        PersistUser(_lastUserName);

                        _dataModule.LoadData(_lastUserName, true);
                    }

                    _invalidUser = false; // reset for next app user request
                });
            }
        }

        /// <summary>
        /// Fires when the View is changed
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="ea"></param>
        private void timeline_ViewChanged(object sender, TimelineEventArgs ea)
        {
            // this centers the last EntryItem in the Timeline window
            CenterLatestItem();
        }

        #region Filtering Events

        private void textBoxSearchTerm_KeyUp(object sender, KeyEventArgs e)
        {
            // refresh UI if the enter key is pressed in the SearchTerm textbox
            if (e.Key == Key.Enter)
            {
                Delegate_CommitMenuChanges();
            }

            removeFilters.Visibility = Visibility.Visible;
        }

        private void buttonClearCache_Click(object sender, RoutedEventArgs e)
        {
            ClearDialogState();
            string nickname = this.autoCompleteBoxUserName.Text;
            MessageBoxResult result = MessageBox.Show("Delete " + nickname + " from the cache?", "Delete User File", MessageBoxButton.OKCancel);

            if (result == MessageBoxResult.OK)
            {
                // try to delete file and then recreate an empty file for the user
                // to get it ready for next request
                _dataModule.DeleteCacheFile(nickname);
                _dataModule.LoadData(nickname, false);
            }
        }

        private void buttonClearSearch_Click(object sender, RoutedEventArgs e)
        {
            this.textBoxSearchTerm.Text = "";
            Delegate_CommitMenuChanges();
        }

        private void listboxDuration_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // select appropriate toggle button and update the timeline with selected view
            View newview = (View)e.AddedItems[0];
            foreach (View view in listboxDuration.Items)
                if (newview != view)
                    view.IsChecked = false;
            newview.IsChecked = true;

            Delegate_CommitMenuChanges();

            
        }

        private void DurationToggleButtonChanged(object sender, RoutedEventArgs e)
        {
            // when user selects a toggle button, also select the ListBoxItem that contains it
            ToggleButton cb = sender as ToggleButton;
            View newview = cb.DataContext as View;
            foreach (View view in listboxDuration.Items)
                if (newview != view)
                    view.IsChecked = false;
            listboxDuration.SelectedIndex = this.listboxDuration.Items.IndexOf(newview);
        }

        private void PopularityCheckChanged(object sender, RoutedEventArgs e)
        {
            Delegate_CommitMenuChanges();

            removeFilters.Visibility = Visibility.Visible;
        }

        private void listboxPopularity_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // toggle checkbox if an item is selected
            (e.AddedItems[0] as PopularityItems).IsChecked = !(e.AddedItems[0] as PopularityItems).IsChecked;
            Delegate_CommitMenuChanges();

            removeFilters.Visibility = Visibility.Visible;
        }

        private void listboxServices_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Delegate_CommitMenuChanges();
            removeFilters.Visibility = Visibility.Visible;
        }

        private void ServiceCheckBoxChanged(object sender, RoutedEventArgs e)
        {
            Delegate_CommitMenuChanges();
            removeFilters.Visibility = Visibility.Visible;
        }

        private void listboxUsers_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // really don't need to do anything when this is selected
        }

        private void UserCheckBoxChanged(object sender, RoutedEventArgs e)
        {
            Delegate_CommitMenuChanges();
            removeFilters.Visibility = Visibility.Visible;
        }

        private void hlUsersSelectAll_Click(object sender, RoutedEventArgs e)
        {
            foreach (User user in listboxUsers.Items)
                user.IsChecked = true;

            Delegate_CommitMenuChanges();

            removeFilters.Visibility = Visibility.Visible;
        }

        private void hlUsersDeselectAll_Click(object sender, RoutedEventArgs e)
        {
            foreach (User user in listboxUsers.Items)
                user.IsChecked = false;

            Delegate_CommitMenuChanges();

            removeFilters.Visibility = Visibility.Visible;
        }

        private void hlServicesSelectAll_Click(object sender, RoutedEventArgs e)
        {
            foreach (Service service in listboxServices.Items)
                service.IsChecked = true;

            Delegate_CommitMenuChanges();

            removeFilters.Visibility = Visibility.Visible;
        }

        private void hlServicesDeselectAll_Click(object sender, RoutedEventArgs e)
        {
            foreach (Service service in listboxServices.Items)
                service.IsChecked = false;

            Delegate_CommitMenuChanges();

            removeFilters.Visibility = Visibility.Visible;
        }

        private void hlPopulartiySelectAll_Click(object sender, RoutedEventArgs e)
        {
            foreach (PopularityItems pi in this.listboxPopularity.Items)
                pi.IsChecked = true;

            Delegate_CommitMenuChanges();

            removeFilters.Visibility = Visibility.Visible;
        }

        private void hlPopulatiryDeselectAll_Click(object sender, RoutedEventArgs e)
        {
            foreach (PopularityItems pi in this.listboxPopularity.Items)
                pi.IsChecked = false;

            Delegate_CommitMenuChanges();

            removeFilters.Visibility = Visibility.Visible;
        }

        private void buttonToggleSearch_Click(object sender, RoutedEventArgs e)
        {
            if (dialogSearch.Visibility == Visibility.Visible)
            {
                ClearDialogState();
                return;
            }
            ClearDialogState();
            
            buttonToggleSearch.IsChecked = true;
            dialogSearch.Visibility = Visibility.Visible;
            gridDialogArea.Visibility = Visibility.Visible;
        }

        private void buttonToggleFriends_Click(object sender, RoutedEventArgs e)
        {

            if (dialogUsers.Visibility == Visibility.Visible)
            {
                ClearDialogState();
                return;
            }
            ClearDialogState();
            
            buttonToggleFriends.IsChecked = true;
            dialogUsers.Visibility = Visibility.Visible;
            gridDialogArea.Visibility = Visibility.Visible;
        }

        private void buttonToggleServices_Click(object sender, RoutedEventArgs e)
        {
            if (dialogServices.Visibility == Visibility.Visible)
            {
                ClearDialogState();
                return;
            }
            ClearDialogState();
            buttonToggleServices.IsChecked = true;
            this.dialogServices.Visibility = Visibility.Visible;
            gridDialogArea.Visibility = Visibility.Visible;
        }

        private void buttonTogglePopularity_Click(object sender, RoutedEventArgs e)
        {
            if (dialogPopularity.Visibility == Visibility.Visible)
            {
                ClearDialogState();
                return;
            }

            ClearDialogState();
            buttonTogglePopularity.IsChecked = true;
            this.dialogPopularity.Visibility = Visibility.Visible;
            gridDialogArea.Visibility = Visibility.Visible;
        }

        private void buttonToggleSettings_Click(object sender, RoutedEventArgs e)
        {
            if (dialogSettings.Visibility == Visibility.Visible)
            {
                ClearDialogState();
                return;
            }
            ClearDialogState();
            buttonToggleSettings.IsChecked = true;
            this.dialogSettings.Visibility = Visibility.Visible;
            gridDialogArea.Visibility = Visibility.Visible;
        }

        private void buttonCloseDialogArea_Click(object sender, RoutedEventArgs e)
        {
            ClearDialogState();
        }

        private void hlRemoveFilters_Click(object sender, RoutedEventArgs e)
        {
            ClearAllFilters();
        }

        #endregion Filtering Events

        #endregion Events

        #region Methods

        /// <summary>
        /// Clears filters that may be applied, if any.
        /// </summary>
        private void ClearAllFilters()
        {

            if (listboxUsers.Items != null)
            {
                // select all users
                foreach (User user in listboxUsers.Items)
                    user.IsChecked = true;
            }

            if (listboxServices.Items != null)
            {
                // select all services
                foreach (Service service in listboxServices.Items)
                    service.IsChecked = true;
            }

            // deselect popularity filters
            foreach (PopularityItems pi in this.listboxPopularity.Items)
                pi.IsChecked = false;

            // remove search filter
            this.textBoxSearchTerm.Text = "";

            Delegate_CommitMenuChanges();

            ClearDialogState();

            removeFilters.Visibility = Visibility.Collapsed;
        }

        /// <summary>
        /// Gets a Bitmap image from a local resource
        /// </summary>
        /// <param name="ImageResourcePath">Path to Resource</param>
        /// <returns></returns>
        private BitmapImage GetImageFromResource(string ImageResourcePath)
        {
            StreamResourceInfo sr = Application.GetResourceStream(new Uri(ImageResourcePath, UriKind.Relative));
            BitmapImage bitmap = new BitmapImage();
            bitmap.SetSource(sr.Stream);
            return bitmap;
        }

        /// <summary>
        /// Events that page subscribes to.
        /// </summary>
        private void SubscribeToEvents()
        {
            _dataModule.StatusChanged += new SurfaceEventHandler(timeline_StatusChanged);
            _dataModule.ItemsChanged += new SurfaceEventHandler(timeline_ItemsChanged);
            timeline.Loaded += new RoutedEventHandler(timeline_Loaded);
            timeline.ViewChanged += new SurfaceEventHandler(timeline_ViewChanged);
            imageProfile.ImageFailed += new EventHandler<ExceptionRoutedEventArgs>(imageProfile_ImageFailed);
        }

        /// <summary>
        /// Initiate getting data from FriendFeed
        /// </summary>
        private void DownloadData()
        {
            string username = this.autoCompleteBoxUserName.Text;

            // show loading dialog
            loadingDialog.Visibility = Visibility.Visible;

            _dataModule.ItemRequestCount = GetItemCount();

#if FRIENDFEEDDATAMODULE // defined in project properties build dialog under "Conditional compilation symbols"
            // let the dataModule know whether it should get friends or not.
            _dataModule.GetFriends = this.checkBoxGetFriends.IsChecked.Value;
#endif

            // has username changed since last get?
            if (username != _lastUserName)
            {
                imageProfile.Source = null;

                _lastUserName = username; //store last used username

                if (_dataModule.UnfilteredItems != null) _dataModule.UnfilteredItems.Clear(); // clear any data
                timeline.virtualizedTimelineItemsControl.Items = new List<Entry>();

                TryGetUserAvatarAndData(username);
            }
            else
            {
                // if same, just try get new data for user
                Delegate_BeginGetData(username);
            }
        }

        /// <summary>
        /// Call BeginGetData asynchronously
        /// </summary>
        /// <param name="username">FriendFree "nickname"</param>
        private void Delegate_BeginGetData(string username)
        {
            // unblock UI
            this.Dispatcher.BeginInvoke(
            delegate
            {
                _dataModule.BeginGetData(username);
            });
        }

        /// <summary>
        /// Call CommitMenuChanges asynchronously
        /// </summary>
        private void Delegate_CommitMenuChanges()
        {
            // unblock UI
            this.Dispatcher.BeginInvoke(
            delegate
            {
                CommitMenuChanges();
            });
        }

        /// <summary>
        /// Applies all filters to datasource and causes the filtered data to be displayed on the Timeline surface.
        /// </summary>
        private void CommitMenuChanges()
        {
            if (listboxUsers.Items != null)
            {
                // Determine User filter
                List<User> filteredUsers = new List<User>();
                foreach (User user in listboxUsers.Items)
                {
                    if (user.IsChecked)
                        filteredUsers.Add(user);
                }

                // Determine Service filter
                List<Service> filteredServices = new List<Service>();
                foreach (Service service in listboxServices.Items)
                {
                    if (service.IsChecked)
                        filteredServices.Add(service);
                }

                /*
                 * apply filters that we need to apply
                 */

                // get all items
#if FRIENDFEEDDATAMODULE
                _filteredEntries = _dataModule.UnfilteredItems;
#endif

                //Determine Like/Comment filters
                foreach (PopularityItems t in listboxPopularity.Items)
                {
                    if (t.Name == "Likes" && t.IsChecked)
                    {
                        // show likes
                        _filteredEntries = _dataModule.FilterEntryByLikes(_filteredEntries);
                    }

                    if (t.Name == "Comments" && t.IsChecked)
                    {
                        // show comments
                        _filteredEntries = _dataModule.FilterEntryByComments(_filteredEntries);
                    }
                }

                _filteredEntries = _dataModule.FilterEntryByUsers(_filteredEntries, filteredUsers);
                _filteredEntries = _dataModule.FilterEntryByServices(_filteredEntries, filteredServices);

                if (!string.IsNullOrEmpty(textBoxSearchTerm.Text))
                    _filteredEntries = _dataModule.FilterEntryBySearchstring(_filteredEntries, textBoxSearchTerm.Text);

                // report
                textBlockStatus.Text = "Displaying " + _filteredEntries.Count.ToString() + " of " + _dataModule.UnfilteredItems.Count() + " posts";


                timeline.Vic.Items = _filteredEntries; // assign data
                timeline.View = listboxDuration.SelectedItem as View; // set View (aka duration). Setting the View commits all changes.
            }
        }

        private Nullable<DateTime> MostRecentItem()
        {
            // find the newest item on the timeline
            List<Entry> allitems;

            if (_filteredEntries == null || _filteredEntries.Count < 1)
            {

                if (_dataModule.UnfilteredItems == null || _dataModule.UnfilteredItems.Count < 1) return null;

                allitems = (from p in _dataModule.UnfilteredItems as IEnumerable<Entry>
                            select p).ToList();
            }
            else
            {
                allitems = (from p in _filteredEntries as IEnumerable<Entry>
                            select p).ToList();
            }

            return allitems.Max(p => p.Published);
        }

        /// <summary>
        /// Gets the number of FriendFeed items to download. Caches the last value specified in the properties dialog.
        /// </summary>
        /// <returns>The number of FriendFeed items to be gotten</returns>
        private int GetItemCount()
        {
            int ItemCount = 200; // set default max to 200 items

            int.TryParse(this.textBoxEntriesToGet.Text, out ItemCount);

            if (ItemCount != 200)
            {
                Storage.SetAppSettingItem("ItemCount", ItemCount); //persist
            }

            return ItemCount;
        }

        /// <summary>
        /// Attempts to get a user icon from FriendFeed.
        /// If it succeeds display the FriendFeed Avatar.
        /// If it fails reset to a clean state.
        /// </summary>
        /// <param name="username">The FriendFeed "nickname"</param>
        private void TryGetUserAvatarAndData(string username)
        {
            if (username.Contains(",")) return;

            // try loading image for user based on nickname
            BitmapImage image = new BitmapImage(new Uri(string.Format(FRIENDFEED_IMAGE_PATH, username)));
            image.DownloadProgress += new EventHandler<DownloadProgressEventArgs>(image_DownloadProgress);
            imageProfile.Source = image;
        }

        /// <summary>
        /// Ensures that the last EntryItem is horizontally centered in the Timeline viewable area,
        /// if there are no recent items in right half of timeline viewable area.
        /// </summary>
        private void CenterLatestItem()
        {
            // get the maximum EntryItem date so that the timeline can be positioned to show the most recent item
            Nullable<DateTime> maxdate = this.MostRecentItem();

            if (maxdate != null)
            {
                // RePosition the timeline based on maxdate
                while (timeline.virtualizedTimelineItemsControl.GetTimelineCenterDateTime() >= maxdate)
                {
                    timeline.virtualizedTimelineItemsControl.MoveTimelineByPixels(50); // creep along at 50px intervals
                }
            }
        }

        /// <summary>
        /// Close all dialogs.
        /// </summary>
        private void ClearDialogState()
        {
            gridDialogArea.Visibility = Visibility.Collapsed;
            dialogSearch.Visibility = Visibility.Collapsed;
            dialogUsers.Visibility = Visibility.Collapsed;
            dialogServices.Visibility = Visibility.Collapsed;
            dialogPopularity.Visibility = Visibility.Collapsed;
            dialogSettings.Visibility = Visibility.Collapsed;
            buttonToggleSearch.IsChecked = false;
            buttonToggleFriends.IsChecked = false;
            buttonToggleServices.IsChecked = false;
            buttonTogglePopularity.IsChecked = false;
            buttonToggleSettings.IsChecked = false;
        }

        /// <summary>
        /// Cache user and the full user list in IsolatedStorage
        /// </summary>
        /// <param name="username"></param>
        private void PersistUser(string username)
        {
            Storage.SetAppSettingItem("UserName", username);

            userMRU = Storage.GetAppSettingItem("UserMRU") as List<string>;
            if (userMRU == null)
            {
                userMRU = new List<string>();
            }

            if (!userMRU.Contains(username))
            {
                userMRU.Add(username);
                autoCompleteBoxUserName.ItemsSource = userMRU;
                Storage.SetAppSettingItem("UserMRU", userMRU);
            }
        }

        #endregion Methods

        #region Privates

        List<Entry> _filteredEntries;
        private const long DESIRED_QUOTA_SIZE = 20000000; // 20Mb
        private string FRIENDFEED_IMAGE_PATH = "http://friendfeed.com/{0}/picture?size=large";
        private string _lastUserName;
        private bool _invalidUser = false;
        private List<string> userMRU;

#if FRIENDFEEDDATAMODULE
        private FriendFeedDataModule _dataModule = new FriendFeedDataModule();
#endif

        #endregion Privates
    }
}
